

<!DOCTYPE html>
<html class="writer-html5" lang="zh" >
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>为 Scrapy 贡献 &mdash; Scrapy 2.3.0 文档</title>
  

  
  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster.custom.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster.bundle.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster-sideTip-shadow.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster-sideTip-punk.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster-sideTip-noir.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster-sideTip-light.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/tooltipster-sideTip-borderless.min.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/micromodal.css" type="text/css" />
  <link rel="stylesheet" href="_static/css/sphinx_rtd_theme.css" type="text/css" />

  
  
  
  

  
  <!--[if lt IE 9]>
    <script src="_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
        <script src="_static/jquery.js"></script>
        <script src="_static/underscore.js"></script>
        <script src="_static/doctools.js"></script>
        <script src="_static/language_data.js"></script>
        <script src="_static/js/hoverxref.js"></script>
        <script src="_static/js/tooltipster.bundle.min.js"></script>
        <script src="_static/js/micromodal.min.js"></script>
    
    <script type="text/javascript" src="_static/js/theme.js"></script>

    
    <link rel="index" title="索引" href="genindex.html" />
    <link rel="search" title="搜索" href="search.html" />
    <link rel="next" title="版本控制和API稳定性" href="versioning.html" />
    <link rel="prev" title="发行说明" href="news.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="index.html" class="icon icon-home" alt="Documentation Home"> Scrapy
          

          
          </a>

          
            
            
              <div class="version">
                2.3
              </div>
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p class="caption"><span class="caption-text">第一步</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="intro/overview.html">Scrapy一目了然</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro/install.html">安装指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro/tutorial.html">Scrapy 教程</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro/examples.html">实例</a></li>
</ul>
<p class="caption"><span class="caption-text">基本概念</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="topics/commands.html">命令行工具</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/spiders.html">蜘蛛</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/selectors.html">选择器</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/items.html">项目</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/loaders.html">项目加载器</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/shell.html">Scrapy shell</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/item-pipeline.html">项目管道</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/feed-exports.html">Feed 导出</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/request-response.html">请求和响应</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/link-extractors.html">链接提取器</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/settings.html">设置</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/exceptions.html">例外情况</a></li>
</ul>
<p class="caption"><span class="caption-text">内置服务</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="topics/logging.html">登录</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/stats.html">统计数据集合</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/email.html">发送电子邮件</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/telnetconsole.html">远程登录控制台</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/webservice.html">Web服务</a></li>
</ul>
<p class="caption"><span class="caption-text">解决具体问题</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="faq.html">常见问题</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/debug.html">调试spiders</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/contracts.html">蜘蛛合约</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/practices.html">常用做法</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/broad-crawls.html">宽爬行</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/developer-tools.html">使用浏览器的开发人员工具进行抓取</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/dynamic-content.html">选择动态加载的内容</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/leaks.html">调试内存泄漏</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/media-pipeline.html">下载和处理文件和图像</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/deploy.html">部署蜘蛛</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/autothrottle.html">AutoThrottle 扩展</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/benchmarking.html">标杆管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/jobs.html">作业：暂停和恢复爬行</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/coroutines.html">协同程序</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/asyncio.html">asyncio</a></li>
</ul>
<p class="caption"><span class="caption-text">扩展Scrapy</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="topics/architecture.html">体系结构概述</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/downloader-middleware.html">下载器中间件</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/spider-middleware.html">蜘蛛中间件</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/extensions.html">扩展</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/api.html">核心API</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/signals.html">信号</a></li>
<li class="toctree-l1"><a class="reference internal" href="topics/exporters.html">条目导出器</a></li>
</ul>
<p class="caption"><span class="caption-text">其余所有</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="news.html">发行说明</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">为 Scrapy 贡献</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#reporting-bugs">报告错误</a></li>
<li class="toctree-l2"><a class="reference internal" href="#writing-patches">编码补丁</a></li>
<li class="toctree-l2"><a class="reference internal" href="#submitting-patches">提交修补程序</a></li>
<li class="toctree-l2"><a class="reference internal" href="#coding-style">编码风格</a></li>
<li class="toctree-l2"><a class="reference internal" href="#documentation-policies">文档策略</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tests">测验</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#running-tests">运行试验</a></li>
<li class="toctree-l3"><a class="reference internal" href="#writing-tests">写作测试</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="versioning.html">版本控制和API稳定性</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="index.html">Scrapy</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
        
      <li>为 Scrapy 贡献</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
            
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="section" id="contributing-to-scrapy">
<span id="topics-contributing"></span><h1>为 Scrapy 贡献<a class="headerlink" href="#contributing-to-scrapy" title="永久链接至标题">¶</a></h1>
<div class="admonition important">
<p class="admonition-title">重要</p>
<p>请仔细检查您是否正在阅读本文档的最新版本，网址为https://docs.scrapy.org/en/master/contributing.html</p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-1466963416408457"
     data-ad-slot="8850786025"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
<p>有很多方法可以为Scrapy做出贡献。 这里是其中的一些：</p>
<ul class="simple">
<li><p>关于Scrapy的博客。告诉全世界你是如何使用Scrapy的。这将有助于新来者提供更多的示例，并有助于 Scrapy 的项目增加其可见性。</p></li>
<li><p>报告“问题跟踪器”中的错误和请求功能，尝试遵循下面“报告错误”中详述的指南。</p></li>
<li><p>提交新功能和/或错误修复的补丁。请阅读 <a class="reference internal" href="#writing-patches"><span class="std std-ref">编码补丁</span></a> 和 <a class="reference internal" href="#id2">Submitting patches</a> 以获取有关如何编写和提交补丁的详细信息。</p></li>
<li><p>加入 <a class="reference external" href="https://reddit.com/r/scrapy">Scrapy subreddit</a> 分享你对如何改善垃圾的想法。我们总是乐于接受建议。</p></li>
<li><p>回答一些 Scrapy 的问题 <a class="reference external" href="https://stackoverflow.com/questions/tagged/scrapy">Stack Overflow</a> .</p></li>
</ul>
<div class="section" id="reporting-bugs">
<h2>报告错误<a class="headerlink" href="#reporting-bugs" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>请报告安全问题 <strong>only</strong> 发送至scrapy-<a class="reference external" href="mailto:security&#37;&#52;&#48;googlegroups&#46;com">security<span>&#64;</span>googlegroups<span>&#46;</span>com</a>。这是一个私人列表，只对受信任的垃圾开发者开放，其档案不公开。</p>
</div>
<p>写得好的bug报告非常有用，因此在报告新bug时，请记住以下指导原则。</p>
<ul class="simple">
<li><p>检查 <a class="reference internal" href="faq.html#faq"><span class="std std-ref">FAQ</span></a> 首先看看你的问题是否在一个众所周知的问题中得到解决</p></li>
<li><p>如果你有一个关于报废使用的一般性问题，请在 <a class="reference external" href="https://stackoverflow.com/questions/tagged/scrapy">Stack Overflow</a> （使用“报废”标签）。</p></li>
<li><p>检查`open issues`_以查看是否已报告该问题。 如果有，请不要关闭该报告，但请检查故障单历史记录和注释。 如果你有其他有用的信息，请发表评论，或者考虑：ref：<a href="#id1"><span class="problematic" id="id2">`</span></a>发送拉动请求&lt;writing-patches&gt;`并修复。</p></li>
<li><p>搜索 <a class="reference external" href="https://groups.google.com/forum/#!forum/scrapy-users">scrapy-users</a> 列表和 <a class="reference external" href="https://reddit.com/r/scrapy">Scrapy subreddit</a> 看看是否在那里讨论过，或者你不确定你所看到的是否是一个bug。您也可以在``#scrapy`` IRC频道中询问。</p></li>
<li><p>写 完整、可复制、特定的错误报告. 测试用例越小越好。请记住，其他开发人员不会让您的项目复制该bug，因此请包括复制该bug所需的所有相关文件。例如，例如，请参阅StackOverflow关于创建“最小，完整且可验证的示例”的指南，该指南展示了该问题。</p></li>
<li><p>提供一个完整的可复制示例的最棒的方法是发送一个pull请求，该请求将一个失败的测试用例添加到Scrapy测试套件中（请参见 <a class="reference internal" href="#submitting-patches"><span class="std std-ref">提交修补程序</span></a> ）即使你不打算自己解决这个问题，这也是有帮助的。</p></li>
<li><p>包括的输出 <code class="docutils literal notranslate"><span class="pre">scrapy</span> <span class="pre">version</span> <span class="pre">-v</span></code> 因此，开发人员在您的bug上准确地知道它发生在哪个版本和平台上，这通常对复制它非常有帮助，或者知道它是否已经被修复了。</p></li>
</ul>
</div>
<div class="section" id="writing-patches">
<span id="id1"></span><h2>编码补丁<a class="headerlink" href="#writing-patches" title="永久链接至标题">¶</a></h2>
<p>补丁编写得越好，它被接受的机会就越高，合并的速度就越快。</p>
<p>写得好的补丁应该：</p>
<ul>
<li><p>包含特定更改所需的最小代码量。小补丁更容易查看和合并。因此，如果您进行了多个更改（或错误修复），请考虑为每个更改提交一个补丁。不要将多个更改折叠为单个修补程序。对于较大的更改，请考虑使用修补程序队列。</p></li>
<li><p>通过所有单元测试。 请参阅下面的“运行测试”。</p></li>
<li><p>包括一个（或多个）测试用例，检查修复的错误或添加的新功能。请参阅下面的“编写测试”。</p></li>
<li><p>如果要添加或更改公共（文档化）API，请在同一补丁中包含文档更改。请参阅下面的“文档策略”。</p></li>
<li><p>如果要添加私有API，请将正则表达式添加到 <code class="docutils literal notranslate"><span class="pre">coverage_ignore_pyobjects</span></code> 变量 <code class="docutils literal notranslate"><span class="pre">docs/conf.py</span></code> 从文档覆盖率检查中排除新的私有API。</p>
<p>要查看是否正确跳过了您的私有API，请生成文档覆盖率报告，如下所示：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span> <span class="o">-</span><span class="n">e</span> <span class="n">docs</span><span class="o">-</span><span class="n">coverage</span>
</pre></div>
</div>
</li>
<li><p>如果要删除不推荐使用的代码，请首先确保自引入不推荐使用的版本以来至少已经过了1年（12个月）。看到了吗 <a class="reference internal" href="versioning.html#deprecation-policy"><span class="std std-ref">弃用政策</span></a> .</p></li>
</ul>
</div>
<div class="section" id="submitting-patches">
<span id="id2"></span><h2>提交修补程序<a class="headerlink" href="#submitting-patches" title="永久链接至标题">¶</a></h2>
<p>提交补丁的最佳方法是在GitHub上发出`pull request`_，可选择先创建一个新问题。</p>
<p>记住解释什么是固定的或新的功能（它是什么，为什么需要它，等等）。您包含的信息越多，核心开发人员就越容易理解和接受您的补丁。</p>
<p>您也可以在创建补丁之前讨论新的功能（或bug修复），但是准备好一个补丁来说明您的论点并表明您已经在主题中添加了一些额外的思想总是很好的。一个好的起点是在Github上发送一个拉请求。它可以很简单地说明您的想法，并将文档/测试留到稍后，在这个想法被验证和证明是有用的之后。或者，您可以在 <a class="reference external" href="https://reddit.com/r/scrapy">Scrapy subreddit</a> 先讨论你的想法。</p>
<p>有时候，为了解决某个问题，你需要解决一些问题。通常拉取请求的方向是正确的，但是变更是由无用的维护人员请求的，而原始的请求请求作者没有时间处理它们。在本例中，请考虑使用这个请求：打开一个新的请求，其中包含来自原始请求的所有提交，以及处理所引发问题的其他更改。这样做很有帮助；只要原著作者通过保持承诺而得到认可，就不会被认为是粗鲁的。</p>
<p>您可以通过运行 <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">fetch</span> <span class="pre">upstream</span> <span class="pre">pull/$PR_NUMBER/head:$BRANCH_NAME_TO_CREATE</span></code> （将“上游”替换为Scrapy存储库的远程名称， <code class="docutils literal notranslate"><span class="pre">$PR_NUMBER</span></code> 带有拉请求的ID，以及 <code class="docutils literal notranslate"><span class="pre">$BRANCH_NAME_TO_CREATE</span></code> 包含要在本地创建的分支的名称）。另请参见：<a class="reference external" href="https://help.github.com/en/github/collaborating">https://help.github.com/en/github/collaborating</a> with issues and pull requests/checking out pull requests local#修改-本地非活动的请求。</p>
<p>在编写Github Pull请求时，请尽量保持标题简短但具有描述性。例如，对于bug 411：“如果启动请求中出现异常，则scrapy将挂起”首选“当启动请求中出现异常时修复挂起”（而不是“修复为411”）。完整的标题使浏览问题跟踪器变得容易。</p>
<p>最后，试着保持审美的变化（ <span class="target" id="index-4"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0008"><strong>PEP 8</strong></a> 合规性、未使用的进口删除等）与功能更改分开提交。这将使pull请求更容易审查，更容易合并。</p>
</div>
<div class="section" id="coding-style">
<span id="id3"></span><h2>编码风格<a class="headerlink" href="#coding-style" title="永久链接至标题">¶</a></h2>
<p>编写要包含在Scrapy中的代码时，请遵循以下编码约定：</p>
<ul class="simple">
<li><p>除非另有规定，遵循 <span class="target" id="index-5"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0008"><strong>PEP 8</strong></a> .</p></li>
<li><p>如果可以提高代码的可读性，那么使用长度超过79个字符的行是可以的。</p></li>
<li><p>不要把你的名字写在你贡献的代码中；git提供了足够的元数据来识别代码的作者。看到了吗https://help.github.com/en/github/using-git/setting-your-username-in-git安装说明。</p></li>
</ul>
</div>
<div class="section" id="documentation-policies">
<span id="id4"></span><h2>文档策略<a class="headerlink" href="#documentation-policies" title="永久链接至标题">¶</a></h2>
<p>对于API成员（类、方法等）的参考文档，请使用docstring并确保sphinx文档使用 <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#module-sphinx.ext.autodoc" title="(在 Sphinx v4.0.0+)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">autodoc</span></code></a> 用于拉取docstrings的扩展。API参考文档应遵循docstring惯例 (<a class="reference external" href="https://www.python.org/dev/peps/pep-0257/">PEP 257</a> ）并且对IDE友好：简短，直截了当，它可能提供简短的示例。</p>
<p>其他类型的文档（如教程或主题）应包含在 <code class="docutils literal notranslate"><span class="pre">docs/</span></code> 目录。这包括特定于API成员的文档，但超出了API参考文档。</p>
<p>在任何情况下，如果文档字符串中包含某些内容，请使用 <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#module-sphinx.ext.autodoc" title="(在 Sphinx v4.0.0+)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">autodoc</span></code></a> 扩展名，用于将docstring拉入文档，而不是在 <code class="docutils literal notranslate"><span class="pre">docs/</span></code> 目录。</p>
<p>包含新功能或修改功能的文档更新必须使用Sphinx的 <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-versionadded" title="(在 Sphinx v4.0.0+)"><code class="xref rst rst-dir docutils literal notranslate"><span class="pre">versionadded</span></code></a> 和 <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-versionchanged" title="(在 Sphinx v4.0.0+)"><code class="xref rst rst-dir docutils literal notranslate"><span class="pre">versionchanged</span></code></a> 指令。使用 <code class="docutils literal notranslate"><span class="pre">VERSION</span></code> 作为版本，我们将在相应版本发布之前用实际版本替换它。当我们发布一个新的主要或次要版本的Scrapy，我们删除这些指令，如果它们超过3年。</p>
<p>必须删除有关不推荐使用的功能的文档，因为这些功能已弃用，这样新的读者就不会碰到它。新的折旧和折旧删除记录在 <a class="reference internal" href="news.html#news"><span class="std std-ref">release notes</span></a> .</p>
</div>
<div class="section" id="tests">
<h2>测验<a class="headerlink" href="#tests" title="永久链接至标题">¶</a></h2>
<p>测试是使用 <a class="reference external" href="https://twistedmatrix.com/documents/current/core/development/policy/test-standard.html" title="(在 Twisted v20.3)"><span class="xref std std-doc">Twisted unit-testing framework</span></a> . 运行测试需要 <a class="reference external" href="https://tox.readthedocs.io/en/latest/index.html" title="(在 tox v3.20)"><span class="xref std std-doc">tox</span></a> .</p>
<div class="section" id="running-tests">
<span id="id5"></span><h3>运行试验<a class="headerlink" href="#running-tests" title="永久链接至标题">¶</a></h3>
<p>要运行所有测试：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span>
</pre></div>
</div>
<p>要运行特定的测试（比如``tests / test_loader.py``），请使用：</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">tox</span> <span class="pre">--</span> <span class="pre">tests/test_loader.py</span></code></p>
</div></blockquote>
<p>在特定的 <a class="reference external" href="https://tox.readthedocs.io/en/latest/index.html" title="(在 tox v3.20)"><span class="xref std std-doc">tox</span></a> 环境，使用 <code class="docutils literal notranslate"><span class="pre">-e</span> <span class="pre">&lt;name&gt;</span></code> 环境名称来自 <code class="docutils literal notranslate"><span class="pre">tox.ini</span></code> . 例如，要使用python 3.6运行测试，请使用：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span> <span class="o">-</span><span class="n">e</span> <span class="n">py36</span>
</pre></div>
</div>
<p>您还可以指定一个逗号分隔的环境列表，并使用 <a class="reference external" href="https://tox.readthedocs.io/en/latest/example/basic.html#parallel-mode" title="(在 tox v3.20)"><span class="xref std std-ref">tox’s parallel mode</span></a> 要在多个环境上并行运行测试，请执行以下操作：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span> <span class="o">-</span><span class="n">e</span> <span class="n">py36</span><span class="p">,</span><span class="n">py38</span> <span class="o">-</span><span class="n">p</span> <span class="n">auto</span>
</pre></div>
</div>
<p>将命令行选项传递到 <a class="reference external" href="https://docs.pytest.org/en/latest/index.html" title="(在 pytest v0.1.dev273+g0a258f5)"><span class="xref std std-doc">pytest</span></a> ，将它们添加到后面 <code class="docutils literal notranslate"><span class="pre">--</span></code> 在你的电话里 <a class="reference external" href="https://tox.readthedocs.io/en/latest/index.html" title="(在 tox v3.20)"><span class="xref std std-doc">tox</span></a> . 使用 <code class="docutils literal notranslate"><span class="pre">--</span></code> 重写中定义的默认位置参数 <code class="docutils literal notranslate"><span class="pre">tox.ini</span></code> ，因此必须包含这些默认位置参数 (<code class="docutils literal notranslate"><span class="pre">scrapy</span> <span class="pre">tests</span></code> ）之后 <code class="docutils literal notranslate"><span class="pre">--</span></code> 也：：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span> <span class="o">--</span> <span class="n">scrapy</span> <span class="n">tests</span> <span class="o">-</span><span class="n">x</span>  <span class="c1"># stop after first failure</span>
</pre></div>
</div>
<p>您也可以使用 <a class="reference external" href="https://github.com/pytest-dev/pytest-xdist">pytest-xdist</a> 插件。例如，在python 3.6上运行所有测试 <a class="reference external" href="https://tox.readthedocs.io/en/latest/index.html" title="(在 tox v3.20)"><span class="xref std std-doc">tox</span></a> 使用所有CPU核心的环境：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tox</span> <span class="o">-</span><span class="n">e</span> <span class="n">py36</span> <span class="o">--</span> <span class="n">scrapy</span> <span class="n">tests</span> <span class="o">-</span><span class="n">n</span> <span class="n">auto</span>
</pre></div>
</div>
<p>To see coverage report install <a class="reference external" href="https://coverage.readthedocs.io/en/stable/index.html" title="(在 Coverage.py v5.3)"><span class="xref std std-doc">coverage</span></a>
(<code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">coverage</span></code>) and run:</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">coverage</span> <span class="pre">report</span></code></p>
</div></blockquote>
<p>有关html或xml报告等更多选项，请参阅``coverage --help``的输出。</p>
</div>
<div class="section" id="writing-tests">
<h3>写作测试<a class="headerlink" href="#writing-tests" title="永久链接至标题">¶</a></h3>
<p>所有功能（包括新功能和错误修复）都必须包含一个测试用例，以检查它是否按预期工作，因此如果您希望补丁能够更快地被接受，请包含对它们的测试。</p>
<p>Scrapy使用单元测试，位于 <a class="reference external" href="https://github.com/scrapy/scrapy/tree/master/tests">tests/</a> 目录。它们的模块名通常类似于所测试模块的完整路径。例如，项目加载器代码位于：：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">scrapy</span><span class="o">.</span><span class="n">loader</span>
</pre></div>
</div>
<p>他们的单元测试在：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">tests</span><span class="o">/</span><span class="n">test_loader</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
</div>
</div>
</div>


           </div>
           
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="versioning.html" class="btn btn-neutral float-right" title="版本控制和API稳定性" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
      
      
        <a href="news.html" class="btn btn-neutral float-left" title="发行说明" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <p>
        
        &copy; 版权所有 2008–2020, Scrapy developers
      <span class="lastupdated">
        最后更新于 10月 18, 2020.
      </span>

    </p>
  </div>
    
    
    
    Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
    
    <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
    
    provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>

        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
  
 
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.1.0";
analytics.load("8UDQfnf3cyFSTsM4YANnW5sXmgZVILbA");
analytics.page();
}}();

analytics.ready(function () {
    ga('require', 'linker');
    ga('linker:autoLink', ['scrapinghub.com', 'crawlera.com']);
});
</script>


</body>
</html>